<template>
  <div class="roles">
    <!-- 面包屑导航 -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-button type="primary" plain @click='addFormVisible = true'>添加用户</el-button>

    <el-table :data="rolesList" border style="width: 100%" class='mt-15' v-loading='loading'>
      <el-table-column type="expand">
        <template slot-scope="scope">
          <!-- 在展开行中，利用el-row和el-col实现布局 -->
          <!-- 循环是循环当前行里面的children，当前行的children表示当前角色具有的所有权限，该权限分三个层级，分别对应三个children -->
          <el-row v-for='firstItem in scope.row.children' :key='firstItem.id' v-show='scope.row.children.length !== 0'>
            <!-- 这里放的是第一个children里面的权限 -->
            <el-col :span='4'>
              <el-tag closable @close='handleDelRight(firstItem.id,scope.row)'>{{firstItem.authName}}</el-tag>
              <i class="el-icon-arrow-right" v-if='firstItem.children.length > 0'></i>
            </el-col>
            <el-col :span='20'>
              <el-row v-for='secondIemt in firstItem.children' :key='secondIemt.id'>
                <!-- 这里放的是第二个children里面的权限 -->
                <el-col :span='4'>
                  <el-tag type='success' closable @close='handleDelRight(secondIemt.id,scope.row)'>{{secondIemt.authName}}</el-tag>
                  <i class="el-icon-arrow-right" v-if='secondIemt.children.length > 0'></i>
                </el-col>
                <el-col :span='20'>
                  <!-- 这里放的是第三个children里面的权限 -->
                  <el-tag closable v-for='thirdItem in secondIemt.children' :key='thirdItem.id' type='warning' @close='handleDelRight(thirdItem.id,scope.row)'>{{thirdItem.authName}}</el-tag>
                </el-col>
              </el-row>
            </el-col>
          </el-row>
          <el-row v-show='scope.row.children.length === 0'>
            <span>该角色没有权限，请前往分配</span>
          </el-row>
        </template>
      </el-table-column>
      <el-table-column type="index" width="50">
      </el-table-column>
      <el-table-column prop="roleName" label="角色名称">
      </el-table-column>
      <el-table-column prop="roleDesc" label="描述">
      </el-table-column>
      <el-table-column prop="mobile" label="操作">
        <template slot-scope="scope">
          <el-button circle type="primary" icon="el-icon-edit"></el-button>
          <el-button circle type="danger" icon="el-icon-delete" @click='handleDelRole(scope.row.id)'></el-button>
          <el-button circle type="warning" icon="el-icon-check" @click='grantRole(scope.row)'></el-button>
        </template>
      </el-table-column>

    </el-table>

    <!-- 添加角色对话框 -->
    <el-dialog title="添加角色" :visible.sync="addFormVisible">
      <!-- js表单验证要先给form表单添加ref属性 -->
      <el-form :model="addForm" ref='addFormRef' :rules="myrules">
        <el-form-item label="角色名称" :label-width="formLabelWidth" prop='roleName'>
          <el-input v-model="addForm.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" :label-width="formLabelWidth" prop='roleDesc'>
          <el-input v-model="addForm.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addFormVisible = false">取 消</el-button>
        <el-button type="primary" @click='submitAdd("addFormRef")'>确 定</el-button>
      </div>
    </el-dialog>

    <!-- 2.2定义授权弹窗 -->
    <el-dialog title="角色授权" :visible.sync="grantFormVisible">
      <!-- 2.3 引入Tree树形控件 -->
      <div class="tree-box">
        <!-- node-key唯一标识每个节点 default-checked-keys用于设置默认选中的节点，注意：父节点会自动被选中 -->
        <el-tree ref='tree' :data="rightList" show-checkbox node-key="id" default-expand-all :default-checked-keys="selectedIds" :props="defaultProps">
        </el-tree>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="grantFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitGrant">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  getRoles,
  delUserRight,
  addRoles,
  deleteRoles,
  getRights,
  grantUserRight
} from '@/api'
export default {
  data () {
    return {
      rolesList: [],
      loading: false,
      formLabelWidth: '80px', // 设置input左侧文字的宽度
      addFormVisible: false,
      addForm: {
        roleName: '',
        roleDesc: ''
      },
      myrules: {
        roleName: [
          { required: true, message: '请输入角色名', trigger: 'blur' }
        ],
        roleDesc: [
          { required: true, message: '请输入角色描述', trigger: 'blur' }
        ]
      },
      // 角色授权数据
      grantFormVisible: false,
      rightList: [],
      defaultProps: {
        children: 'children', // 指定子节点
        label: 'authName' // 指定显示内容对应的属性值
      },
      selectedIds: [], // 用来获取默认选中节点数组
      currentRole: {} // 2.12 存储当前点击的角色数据
    }
  },
  created () {
    this.initTable()
  },
  methods: {
    initTable () {
      getRoles().then(res => {
        console.log(res)
        this.rolesList = res.data
      })
    },
    // 删除权限
    handleDelRight (rightId, row) {
      // 调用发请求的接口,传递权限id，以及角色id（即那一行数据的id）
      console.log(rightId, row.id)
      delUserRight(rightId, row.id).then(res => {
        // 返回值是返回的当前角色所具有新的所有权限
        console.log(res)
        // 用服务器返回的新的所有权限，替换掉原来的权限（原来的所有权限全部保存在第一层children里面的），从而避免再多发一次请求去刷新列表数据
        row.children = res.data
      })
    },
    // 添加角色
    submitAdd (formRef) {
      this.$refs[formRef].validate(isPass => {
        if (isPass) {
          addRoles(this.addForm).then(res => {
            console.log(res)
            if (res.meta.status === 201) {
              // 添加角色成功
              this.$message.success('添加角色成功')
              this.addForm.roleName = ''
              this.addForm.roleDesc = ''
              this.addFormVisible = false
              this.initTable()
              console.log(res)
            }
          })
        }
      })
    },
    // 删除角色
    handleDelRole (id) {
      // 让提示框显示
      this.$confirm('确定要删除角色吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 点击确定执行的回调函数
          deleteRoles(id).then(res => {
            if (res.meta.status === 200) {
              this.$message({
                type: 'success',
                message: '删除成功！'
              })
              this.initTable()
              console.log(this.rolesList)
            } else {
              this.$message.error(res.meta.msg)
            }
          })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    // 2.1 显示授权角色弹框
    // 2.6 需要将点击的那一行数据传入函数中
    grantRole (row) {
      this.grantFormVisible = true
      // 2.12 在点击授权角色的时候，应该将当前那一行数据存起来，因为在点击提交的时候，需要用到这一行的角色id
      this.currentRole = row
      // 2.4 获取树形控件数据
      getRights('tree').then(res => {
        console.log(res)
        this.rightList = res.data
        // 2.5 为了得到获取默认选中节点id的数组，我们需要将点击的哪个角色（也就是那一行数据）的第三层权限的id取出来放进数组中

        // 2.7 在每次循环获取selectedIds数组时，应该先给数组清空
        this.selectedIds.length = 0

        // 先循环最外层的children
        row.children.forEach(firstItem => {
          // 循环第二层children的时候要先判断第二层的children是否存在并有值
          if (firstItem.children && firstItem.children.length > 0) {
            firstItem.children.forEach(secondItem => {
              // 循环第三层children的时候要先判断第三层的children是否存在并有值
              if (secondItem.children && secondItem.children.length > 0) {
                secondItem.children.forEach(thirdItem => {
                  this.selectedIds.push(thirdItem.id)
                })
              }
            })
          }
        })
      })
    },
    // 提交角色授权
    submitGrant () {
      console.log('提交')
      // // 2.8 先获取用户修改之后，选中的节点的id，获取选中节点用getCheckedNodes(),因为它能够获取到父节点id
      // let nodeObj = this.$refs.tree.getCheckedNodes()
      // // 2.9 获取所有id和pid组成的数组 -- map()会遍历当前数组
      // let tempArr = nodeObj.map(item => item.id + ',' + item.pid)
      // console.log(tempArr)// 结果不符合需求，需要拼接
      // let repeatedIdArr = tempArr.join(',').split(',') //  ["105", "104", "101", "116", "104", "101"]
      // // 2.10 将上面得到的数组去重
      // // Set类型的数据有个特点，它的值是不重复的
      // let myset = new Set(repeatedIdArr)
      // let idArr = [...mys1et]
      // // 2.11 得到需要传递的字符串
      // let idStrs = idArr.join(',')

      let childKeys = this.$refs.tree.getCheckedKeys() // 选中节点
      let fatherKeys = this.$refs.tree.getHalfCheckedKeys() // 半选中节点（父节点，所有子节点都选中时，变为选中）
      let idArr = [...childKeys, ...fatherKeys]
      let idStrs = idArr.join(',')
      console.log(idStrs)

      grantUserRight(this.currentRole.id, idStrs).then(res => {
        console.log(res)
        // 刷新列表，关闭弹窗，提示信息
        this.initTable()
        this.grantFormVisible = false
        this.$message.success(res.meta.msg)
      })
    }
  }
}
</script>
<style lang="scss" scoped>
  .roles {
    .el-tag {
      margin-top: 5px;
    }
    .tree-box {
      height: 350px;
      overflow: auto;
    }
  }
</style>
